import { defineStore } from "pinia";
import {
  type userType,
  store,
  router,
  resetRouter,
  routerArrays,
  storageLocal,
  readDeviceId
} from "../utils";
import {
  type UserTokenResult,
  type UserResult,
  accessUserLogin,
  refreshAccessToken,
  getAccessUserInfo
} from "@/api/access";
import { useMultiTagsStoreHook } from "./multiTags";
import {
  type DataInfo,
  setToken,
  removeToken,
  userKey,
  setUserData
} from "@/utils/auth";
import { useMessageStoreHook } from "./message";

export const useUserStore = defineStore("pure-user", {
  state: (): userType => ({
    // UID
    uid: storageLocal().getItem<DataInfo>(userKey)?.uid ?? 0,
    // 用户名
    username: storageLocal().getItem<DataInfo>(userKey)?.username ?? "",
    // 昵称
    nickname: storageLocal().getItem<DataInfo>(userKey)?.nickname ?? "",
    // 手机
    phone: storageLocal().getItem<DataInfo>(userKey)?.phone ?? "",
    // 邮箱
    email: storageLocal().getItem<DataInfo>(userKey)?.email ?? "",
    // 页面级别权限
    roles: storageLocal().getItem<DataInfo>(userKey)?.roles ?? [],
    // 按钮级别权限
    permissions: storageLocal().getItem<DataInfo>(userKey)?.permissions ?? [],
    // 备注
    remark: storageLocal().getItem<DataInfo>(userKey)?.remark ?? ""
  }),
  actions: {
    /** 存储UID */
    SET_UID(uid: number) {
      this.uid = uid;
    },
    /** 存储用户名 */
    SET_USERNAME(username: string) {
      this.username = username;
    },
    /** 存储昵称 */
    SET_NICKNAME(nickname: string) {
      this.nickname = nickname;
    },
    /** 存储手机 */
    SET_PHONE(phone: string) {
      this.phone = phone;
    },
    /** 存储邮箱 */
    SET_EMAIL(email: string) {
      this.email = email;
    },
    /** 存储角色 */
    SET_ROLES(roles: Array<string>) {
      this.roles = roles;
    },
    /** 存储按钮级别权限 */
    SET_PERMS(permissions: Array<string>) {
      this.permissions = permissions;
    },
    /** 存储备注 */
    SET_REMARK(remark: string) {
      this.remark = remark;
    },
    /** 登入 */
    async loginByUsername(passport: string, password: string) {
      return new Promise<UserResult>(async (resolve, reject) => {
        try {
          const loginRes = await accessUserLogin({
            passport,
            password,
            deviceId: readDeviceId()
          });
          // 注：这里需要首先将登录后获取的token存储，以方便后续获取用户信息
          // 也可以通过修改后端api，在登录后一并返回用户信息，减少一次请求
          setToken(loginRes.data);
          const infoRes = await this.refreshUserInfo();
          resolve(infoRes);
        } catch (e) {
          reject(e);
        }
      });
    },
    /** 刷新用户信息 */
    async refreshUserInfo() {
      return new Promise<UserResult>(async (resolve, reject) => {
        try {
          const infoRes = await getAccessUserInfo();
          setUserData(infoRes.data);
          resolve(infoRes);
        } catch (e) {
          reject(e);
        }
      });
    },
    /** 前端登出（不调用接口） */
    logOut() {
      this.uid = 0;
      this.username = "";
      this.nickname = "";
      this.phone = "";
      this.email = "";
      this.roles = [];
      this.permissions = [];
      this.remark = "";
      removeToken();
      useMultiTagsStoreHook().handleTags("equal", [...routerArrays]);
      resetRouter();
      useMessageStoreHook().clearMsgStore();
      router.push("/login");
    },
    /** 刷新`token` */
    async handRefreshToken(refreshToken: string) {
      return new Promise<UserTokenResult>((resolve, reject) => {
        refreshAccessToken({
          uid: this.uid,
          deviceId: readDeviceId(),
          refreshToken
        })
          .then(res => {
            setToken(res.data);
            resolve(res);
          })
          .catch(error => {
            reject(error);
          });
      });
    }
  }
});

export function useUserStoreHook() {
  return useUserStore(store);
}
